package com.woniuxy.charin.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.charin.enumeration.*;
import com.woniuxy.charin.mapper.EventDisposeMapper;
import com.woniuxy.charin.mapper.EventMapper;
import com.woniuxy.charin.mapper.FormMapper;
import com.woniuxy.charin.model.entity.*;
import com.woniuxy.charin.model.request.AssignProcessorsRequest;
import com.woniuxy.charin.model.request.DisposeEventRequest;
import com.woniuxy.charin.model.vo.EventDetailVo;
import com.woniuxy.charin.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author WH
 * @description 针对表【event_dispose】的数据库操作Service实现
 * @createDate 2024-12-25 10:30:21
 */
@Service
public class EventDisposeServiceImpl extends ServiceImpl<EventDisposeMapper, EventDispose>
        implements EventDisposeService {
    @Autowired
    EventMapper eventMapper;
    @Autowired
    EventDisposeMapper eventDisposeMapper;
    @Autowired
    FormMapper formMapper;
    @Autowired
    ChargingPileService chargingPileService;
    @Autowired
    StationService stationService;

    //获取全部处理人相关
    @Autowired
    RoleService roleService;
    @Autowired
    UserRoleService userRoleService;
    @Autowired
    UserService userService;

    @Override
    public Page<EventDetailVo> pageFaultDisposeByUserId(Integer userId, Integer pageNum, Integer pageSize, Integer status, Date startDate, Date endDate) {
        endDate = addDay(endDate, 1);
        Page<EventDetailVo> eventDetailVoPage = pageEventDisposeByType(userId, pageNum, pageSize, EventType.FAULT.getKey(), status, startDate, endDate);
        return eventDetailVoPage;
    }

    @Override
    public Page<EventDetailVo> pageRiskDisposeByUserId(Integer userId, Integer pageNum, Integer pageSize, Integer status, Date startDate, Date endDate) {
        endDate = addDay(endDate, 1);
        Page<EventDetailVo> eventDetailVoPage = pageEventDisposeByType(userId, pageNum, pageSize, EventType.RISK.getKey(), status, startDate, endDate);
        return eventDetailVoPage;
    }

    @Override
    public User getProcessorsInfo(Integer processorsId) {
        User user = userService.getById(Long.valueOf(processorsId));
        Assert.error(user.getStatus() != 1, EventCode.PROCESSORS_IS_EMPTY);
        return user;
    }

    @Override
    public List<User> getAllProcessors() {
        Role role = roleService.getOne(Wrappers.lambdaQuery(Role.class).eq(Role::getRoleName, "工程师"));
        List<UserRole> list = userRoleService.list(Wrappers.lambdaQuery(UserRole.class).eq(UserRole::getRoleId, role.getRoleId()));
        Assert.error(list.isEmpty(), EventCode.PROCESSORS_IS_EMPTY);
        List<Integer> userId = list.stream().map(l -> l.getUserId()).collect(Collectors.toList());
        List<User> users = userService.listByIds(userId).stream()
                .filter(user -> user.getStatus() == 1)
                .collect(Collectors.toList());
        return users;
    }

    //故障相关操作====================================================

    @Override
    public Page<EventDetailVo> pageFaultDispose(Integer userId, Integer pageNum, Integer pageSize, Integer status, Date startDate, Date endDate) {
        endDate = addDay(endDate, 1);
        Page<EventDetailVo> eventDetailVoPage = pageEventDisposeByType(userId, pageNum, pageSize, EventType.FAULT.getKey(), status, startDate, endDate);
        return eventDetailVoPage;
    }

    //故障相关操作====================================================
    @Override
    public void assignProcessors(AssignProcessorsRequest request) {
        //获取事件id
        Long eventId = request.getEventId();
        //获取其他信息
        Long processorsId = request.getProcessorsId(); //处理人id
        String taskContent = request.getTaskContent(); //任务内容
        Date estimatedTime = request.getEstimatedTime(); //预计完成时间
        //事件表相关改动
        Event event = eventMapper.selectById(eventId);
        event.setCurrentProcessorsId(processorsId);
        event.setCurrentStatus(EventStatus.PROCESSING.getKey());
        eventMapper.updateById(event);
        //处理表相关改动
        EventDispose eventDispose = new EventDispose();
        eventDispose.setEventId(eventId);
        eventDispose.setStatus(EventDisposeStatus.PROCESSING.getKey());
        eventDispose.setProcessorsId(processorsId);
        eventDispose.setEstimatedTime(estimatedTime);
        eventDispose.setTaskContent(taskContent);
        eventDisposeMapper.insert(eventDispose);
        System.out.println("处理人指派成功");

//        addForm(Math.toIntExact(eventId),event.getEventType(), Math.toIntExact(event.getCurrentProcessorsId()));
    }

    @Override
    public void ResendProcessors(AssignProcessorsRequest request,String token) {
        //获取事件id
        Long eventId = request.getEventId();
        //获取其他信息
        Long processorsId = request.getProcessorsId(); //处理人id
        String taskContent = request.getTaskContent(); //任务内容
        Date estimatedTime = request.getEstimatedTime(); //预计完成时间
        //获取原处理人id
        Long oldProcessorsId = request.getOldProcessorsId();

        //如果重派处理人与原处理人相同,则只更新处理任务、预计完成时间部分
        if (processorsId == oldProcessorsId) {
            EventDispose oldEventDispose = eventDisposeMapper.selectOne(Wrappers.lambdaQuery(EventDispose.class)
                    .eq(EventDispose::getEventId, eventId)
                    .eq(EventDispose::getProcessorsId, oldProcessorsId)
                    .eq(EventDispose::getStatus, EventDisposeStatus.PROCESSING.getKey())
            );
            oldEventDispose.setTaskContent(taskContent);
            oldEventDispose.setEstimatedTime(estimatedTime);
            eventDisposeMapper.updateById(oldEventDispose);
            System.out.println("处理人重派成功");
        } else {
            //判断是否有重派资格
            Integer count = eventDisposeMapper.selectCount(Wrappers.lambdaQuery(EventDispose.class)
                    .eq(EventDispose::getEventId, eventId)
                    .eq(EventDispose::getProcessorsId, oldProcessorsId)
                    .eq(EventDispose::getStatus, EventDisposeStatus.REFERRED.getKey()));
            Assert.error(count>=2,EventCode.PROCESSORS_REASSIGNMENTS_EMPTY);

            //判断是否满足重派条件
            Integer riskCount=eventDisposeMapper.statisticsEventByType(Math.toIntExact(processorsId),EventType.RISK.getKey());
            Integer faultCount=eventDisposeMapper.statisticsEventByType(Math.toIntExact(processorsId),EventType.FAULT.getKey());
            Integer sum=riskCount+faultCount;
            Assert.error(sum>=6,EventCode.PROCESSORS_EVENT_PLETHORA);

            //事件表相关改动
            Event event = eventMapper.selectById(eventId);
            event.setCurrentProcessorsId(processorsId);
            event.setCurrentStatus(EventStatus.PROCESSING.getKey());
            eventMapper.updateById(event);
            //处理表相关改动
            //------原处理人相关
            EventDispose oldEventDispose = eventDisposeMapper.selectOne(Wrappers.lambdaQuery(EventDispose.class)
                    .eq(EventDispose::getEventId, eventId)
                    .eq(EventDispose::getProcessorsId, oldProcessorsId)
                    .eq(EventDispose::getStatus, EventDisposeStatus.PROCESSING.getKey())
            );
            oldEventDispose.setStatus(EventDisposeStatus.REFERRED.getKey());
            eventDisposeMapper.updateById(oldEventDispose);
            //------现处理人
            EventDispose eventDispose = new EventDispose();
            eventDispose.setEventId(eventId);
            eventDispose.setStatus(EventDisposeStatus.PROCESSING.getKey());
            eventDispose.setProcessorsId(processorsId);
            eventDispose.setEstimatedTime(estimatedTime);
            eventDispose.setTaskContent(taskContent);
            eventDisposeMapper.insert(eventDispose);
            System.out.println("处理人重派成功");

//            updateFormStatus(Math.toIntExact(eventId),event.getEventType(), Math.toIntExact(oldProcessorsId),"已转派");
//            addForm(Math.toIntExact(eventId),event.getEventType(), Math.toIntExact(event.getCurrentProcessorsId()));
        }
    }

    @Override
    public void disposeEvent(DisposeEventRequest request) {
        //提取信息
        Long eventDisposeId = request.getEventDisposeId();
        String transactIllustrate = request.getTransactIllustrate();
        String sceneImageUrl = request.getSceneImageUrl();
        String annex = request.getAnnex();
        //更新处理表中信息
        EventDispose eventDispose = eventDisposeMapper.selectById(eventDisposeId);
        eventDispose.setStatus(EventDisposeStatus.DONE.getKey());
        eventDispose.setTransactIllustrate(transactIllustrate);
        eventDispose.setSceneImageUrl(sceneImageUrl);
        eventDispose.setAnnex(annex);
        eventDisposeMapper.updateById(eventDispose);
        //更新事件表中信息
        Long eventId = eventDispose.getEventId();
        Event event = eventMapper.selectById(eventId);
        event.setCurrentStatus(EventStatus.DONE.getKey());
        eventMapper.updateById(event);

        //如果事件类型为故障，则将充电桩状态改回空闲中（修改充电桩状态）
        if (event.getEventType() == EventType.FAULT.getKey()) {
            chargingPileService.offlineChargingPile(Math.toIntExact(event.getChargingPileId()));
        }

        System.out.println("处理人处理事件成功");
//        updateFormStatus(Math.toIntExact(eventId),event.getEventType(), Math.toIntExact(event.getCurrentProcessorsId()),"已处理");
    }

    @Override
    public Page<EventDetailVo> pageRiskDispose(Integer userId, Integer pageNum, Integer pageSize, Integer status, Date startDate, Date endDate) {
        endDate = addDay(endDate, 1);
        Page<EventDetailVo> eventDetailVoPage = pageEventDisposeByType(userId, pageNum, pageSize, EventType.RISK.getKey(), status, startDate, endDate);
        return eventDetailVoPage;
    }

    @Override
    public EventDetailVo getDetailByDisposeId(Integer disposeId) {
        EventDispose eventDispose = eventDisposeMapper.selectById(disposeId);
        Event event = eventMapper.selectById(eventDispose.getEventId());

        EventDetailVo detailVo = new EventDetailVo();
        detailVo.setEvent(event);
        detailVo.setEventDispose(eventDispose);

        return detailVo;
    }

    @Override
    public void editDisposeDetail(DisposeEventRequest request) {
        //提取信息
        Long eventDisposeId = request.getEventDisposeId();
        String transactIllustrate = request.getTransactIllustrate();
        String sceneImageUrl = request.getSceneImageUrl();
        String annex = request.getAnnex();
        //更新处理表中信息
        EventDispose eventDispose = eventDisposeMapper.selectById(eventDisposeId);
        eventDispose.setTransactIllustrate(transactIllustrate);
        eventDispose.setSceneImageUrl(sceneImageUrl);
        eventDispose.setAnnex(annex);
        eventDisposeMapper.updateById(eventDispose);
    }

    @Override
    public List<Integer> statisticsCurrentUserEvent(Integer userId, Integer type) {
        Integer processingCount = eventDisposeMapper.statisticsEventByType(userId, type);
        //创建阈值时间
        Date date = new Date();
        Date thresholdDate = addDay(date, 3);
        Integer overdueCount = eventDisposeMapper.statisticsOverdueEventByType(userId, type, thresholdDate);

        List<Integer> statistics = new ArrayList<>();
        statistics.add(processingCount);
        statistics.add(overdueCount);
        return statistics;
    }

    //用于事件处理界面，查找所有与当前用户相关事件
    private Page<EventDetailVo> pageEventDisposeByType(Integer userId, Integer pageNum, Integer pageSize, Integer type, Integer status, Date startDate, Date endDate) {
        //创建EventDispose的分页对象
        IPage<EventDispose> eventPage = new Page<>(pageNum, pageSize);
        eventDisposeMapper.selectPageEventDisposes(eventPage, type, userId, status, startDate, endDate);

//        //构建条件选择器
//        LambdaQueryWrapper<EventDispose> queryWrapper = Wrappers.lambdaQuery(EventDispose.class)
//                .select()
//                .orderByDesc(EventDispose::getEstimatedTime);
//        // 如果startDate和endDate都不为null，则添加between条件
//        if (startDate != null && endDate != null) {
//            queryWrapper.between(EventDispose::getEstimatedTime, startDate, endDate);
//        }
//        // 如果status不为null，则添加条件
//        if (status != null) {
//            queryWrapper.eq(EventDispose::getStatus, status);
//        }
//        //根据用户id查找（现在先注销，后续开放）
//        queryWrapper.eq(EventDispose::getProcessorsId, userId);
//        //开始查找，查找结果返回EventDispose的分页对象
//        eventDisposeMapper.selectPage(eventPage, queryWrapper);

        //创建EventDetailVo集合，为后续将分页对象中EventDispose集合转换为EventDetailVo集合做准备
        List<EventDetailVo> eventDetailVos = new ArrayList<>();
        //获取分页对象中原始查找结果集合
        List<EventDispose> records = eventPage.getRecords();
        //遍历原始查找结果，并开始转换为EventDetailVo
        records.forEach(record -> {
            User processors = userService.getById(record.getProcessorsId());
            record.setProcessorsAccount(processors);
            //创建一个空的EventDetailVo对象
            EventDetailVo detailVo = new EventDetailVo();
            //为空对象赋值
            detailVo.setEventDispose(record);
            //根据处理记录，回溯事件信息
            Event event = eventMapper.selectById(record.getEventId());
            // 查询充电桩信息
            ChargingPile chargingPile = chargingPileService.getChargingPileById(Math.toIntExact(event.getChargingPileId()));
            Station station = stationService.getById(chargingPile.getStationId()); // 查询充电站信息
            String stationName = station.getStationName();
            String pileCode = chargingPile.getPileCode();
            String address = station.getAddress();
            //赋值给event
            event.setStationName(stationName);
            event.setPileCode(pileCode);
            event.setAddress(address);

            //为空对象赋值
            detailVo.setEvent(event);
            //将该空对象放入，先前创建的EventDetailVo集合
            eventDetailVos.add(detailVo);
        });
        //对EventDetailVo集合进行最后的筛选，筛选出只含有隐患处理的记录
        List<EventDetailVo> collect = eventDetailVos.stream()
                .filter(eventDetailVo -> EventType.RISK.getKey().equals(eventDetailVo.getEvent().getEventType()))
                .collect(Collectors.toList());
        //创建EventDetailVo的分页对象，用于后续返回
        Page<EventDetailVo> eventVoPage = new Page<>(pageNum, pageSize, eventPage.getTotal());
        //将筛选结果放入该分页对象
        eventVoPage.setRecords(eventDetailVos);
        return eventVoPage;
    }

    // 用于将Date对象增加一天
    private Date addDay(Date date, Integer days) {
        if (date == null) {
            return null;
        }
        // 将Date转换为Instant
        Instant instant = date.toInstant();
        // 将Instant转换为ZonedDateTime以便进行日期加减
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
        // 增加一天
        ZonedDateTime newZonedDateTime = zonedDateTime.plusDays(days);
        // 将新的ZonedDateTime转换回Instant
        Instant newInstant = newZonedDateTime.toInstant();
        // 将Instant转换回Date
        Date newDate = Date.from(newInstant);
        return newDate;
    }

//    //添加一条数据到form表中
//    private void addForm(Integer eventId, Integer eventType, Integer userId) {
//        Form form = new Form();
//        form.setFormId(eventId);
//        String modelName = eventType == EventType.RISK.getKey() ? "隐患管理" : "故障管理";
//        form.setModelName(modelName);
//        form.setUserId(userId);
//        form.setStatus("待审核");
//        formMapper.insert(form);
//    }
//
//    //删除form表中数据
//    private void updateFormStatus(Integer eventId, Integer eventType, Integer userId, String status) {
//        Form form = formMapper.selectOne(Wrappers.lambdaQuery(Form.class)
//                .eq(Form::getFormId, eventId)
//                .eq(Form::getModelName, eventType == EventType.RISK.getKey() ? "隐患管理" : "故障管理")
//                .eq(Form::getUserId, userId)
//                .eq(Form::getStatus, "待审核"));
//        form.setStatus(status);
//        formMapper.updateById(form);
//    }
}




